/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.gui.query;

import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Panel;

import nfse.gui.client.*;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.gwtext.client.widgets.*;
import com.gwtext.client.widgets.event.*;
import com.gwtext.client.data.*;    
import com.gwtext.client.widgets.grid.ColumnConfig;  
import com.gwtext.client.widgets.grid.ColumnModel;  
import com.gwtext.client.widgets.grid.GridPanel;  
import com.gwtext.client.widgets.grid.*;
import com.gwtext.client.core.EventObject; 
import com.gwtext.client.core.*;
import com.gwtext.client.widgets.layout.*; 

import nfse.gui.util.GUIUtil;

import java.util.*;

//public class SearchHistoryPanel extends com.google.gwt.user.client.ui.FlexTable
public class SearchHistoryPanel extends Panel
{
	NetFSEClient client = null;
	 private HashMap checkedHistoryIDs = new HashMap();
	
    private GridPanel grid = new GridPanel();

    CheckboxSelectionModel cbSelectionModel = new CheckboxSelectionModel();
    
    private final Panel buttonPanel = new Panel();    
    
    private final Button setSearchQueryButton = new Button("Set Search Criteria");
    private final Button deleteButton = new Button("Delete");
    private final Button refreshButton = new Button("Refresh");
    
    boolean refreshHistoryGridNow = false;
    
	    public SearchHistoryPanel(NetFSEClient client)
	    {
			this.client = client;
			this.setTitle("History");
			this.setClosable(false);
			this.setAutoWidth(true);
			this.setLayout(new FitLayout());
			grid = new GridPanel();
			grid.setStripeRows(true);
			grid.setAutoWidth(true);
			grid.setAutoScroll(true);  
			grid.setEnableColumnResize(true);  
			grid.setEnableDragDrop(false);  
			grid.setEnableColumnHide(false);  
			grid.setEnableColumnMove(true);  			
			grid.setAutoExpandColumn(5);
			grid.setAutoExpandMin(150);
			
			queryHistory();
	    }
    
	
	   private synchronized void deleteQueryHistories(String[] queryIDs) {
	        final String[] tempQueryIDs = queryIDs;
	        String msg = "";
	        if (queryIDs.length == 1) {
	            msg = "Are you sure you want to delete the Search Histories for Search " + queryIDs[0] + "?";
	        } else {
	            msg = "The following Search Histories will be deleted: ";
	            for (int i = 0; i < queryIDs.length; i++) {
	                msg += queryIDs[i];
	                if (i != queryIDs.length - 1) {
	                    msg += ", ";
	                }
	            }
	            msg += ".\n Are you sure you want to delete these Search History entries?";
	        }

	        MessageBox.confirm("Confirm", msg, new MessageBox.ConfirmCallback() {
	            public void execute(String btnID) {
	                if (btnID.equals("yes")) {
	                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

	                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
	                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

	                    AsyncCallback callback = new AsyncCallback() 
	                    {
	                        public void onFailure(Throwable caught) 
	                        {
	                        	NetFSEClient.redirect("NetFSEClient.html");
	                        }

	                        public void onSuccess(Object result) 
	                        {
	                            Record[] records = cbSelectionModel.getSelections();
	                            for (int i = 0; i <  records.length; i++) 
	                            {
	                                checkedHistoryIDs.remove(records[i].getAsString("Search Id"));
	                            }
	                            queryHistory();
	                        }
	                    };

	                    NetFSEService.multiQueryHistoryDelete(tempQueryIDs, callback);
	                }
	            }
	        });
	        
	        

	    }


	    public QueryOptions[] historyData;
	    
	    public QueryOptions[] getHistoryData()
	    {
	    	return historyData;
	    }
	    public void setHistoryData(QueryOptions[] options)
	    {
	    	this.historyData = options;
	    }  
	    
	    public void queryHistory() {

	        QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

	        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
	        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

	        AsyncCallback callback = new AsyncCallback() {
	            public void onFailure(Throwable caught) {
	                NetFSEClient.redirect("NetFSEClient.html");
	            }

	            public void onSuccess(Object result) {
	                QueryOptions[] options = (QueryOptions[]) result;
	                setHistoryData(options);
	                if (refreshHistoryGridNow)
	                {
	                	refreshHistoryGridNow = false;
	                	refreshHistoryGrid();
	                }
	                else	                	
	                	checkForBuild();
	            }
	        };

	        nfseService.queryHistory(callback);
	    }
	    
	    public void checkForBuild()
	    {
    		client.checkIfReadyToBuild(this);
	    }
	
	    public void setSearchQuery(String[] queryIds)
	    {
	        if (queryIds.length != 1) {
	            MessageBox.alert("You must select just one query id to populate the search form.");
	            return;
	        } 

            QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

            ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
            endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

            AsyncCallback callback = new AsyncCallback() 
            {
                public void onFailure(Throwable caught) 
                {
                	NetFSEClient.redirect("NetFSEClient.html");
                }

                public void onSuccess(Object result) 
                {
        	        client.setSearchCriteria((QueryOptions)result);
                }
            };

            NetFSEService.getSearchQuery(queryIds[0], callback);	        
	    }
	    
	    public void buildPanel()
	    {
	    	buttonPanel.setBaseCls("button-panel");	    		    	
	    	setSearchQueryButton.addListener( new ButtonListenerAdapter() 
	    		{  
	    		             public void onClick(Button button, EventObject e) 
	    		             {
	    		            	 Record[] records = cbSelectionModel.getSelections();
	    		            	 String[] queryIds = new String[records.length];
	    		            	 for (int i = 0; i < records.length; i++)
	    		            		 queryIds[i] = records[i].getAsString("Search Id");
	    		            	 setSearchQuery(queryIds); 
	    		             }
	    		}
	    	);	    	
	    	buttonPanel.addButton(setSearchQueryButton);
	    	refreshButton.addListener( new ButtonListenerAdapter() 
		    	{  
		    		             public void onClick(Button button, EventObject e) 
		    		             {
		    		            	 refreshHistoryGridNow = true;
		    		            	 queryHistory();
		    		             }
		    	}
	    	);	    	
	    	buttonPanel.addButton(refreshButton);
	    	
	    	deleteButton.addListener( new ButtonListenerAdapter() 
		    	{  
		    		             public void onClick(Button button, EventObject e) 
		    		             {
		    		     	    	Record[] records = cbSelectionModel.getSelections();
		    		    	    	String[] queryIds = new String[records.length];
		    		                for (int x = 0; x < records.length; x++)
		    		                {
		    		               	 System.out.println("The query id is " + records[x].getAsString("Search Id"));
		    		               	 queryIds[x] = records[x].getAsString("Search Id");           	 
		    		                }		    		            	 
		    		            	 
		    		            	 refreshHistoryGridNow = true;
		    		            	 deleteQueryHistories(queryIds);
		    		             }
		    		             
		    	}
            );	    	
	    	buttonPanel.addButton(deleteButton);

	    	buttonPanel.setButtonAlign(Position.LEFT);	    
	    	Panel gridHolder = new Panel();
	    	gridHolder.setLayout(new BorderLayout());
	    	gridHolder.add(createHistoryGrid(),new BorderLayoutData(com.gwtext.client.core.RegionPosition.CENTER));
	    	gridHolder.add(buttonPanel,new BorderLayoutData(com.gwtext.client.core.RegionPosition.NORTH));
		    this.add(gridHolder);
		    
	    }
	    
	    public GridPanel createHistoryGrid()
	    {
	    	setColumnNameList();
			Object[][] data = convertRawDataToObjectGrid();

			//The columns names are not determined until after the data Object[][] has been processed
			RecordDef recordDef = buildRecordDef();
			
			
			if (data != null)
			{
				MemoryProxy proxy = new MemoryProxy(data);
				
				ArrayReader reader = new ArrayReader(recordDef);
				Store store = new Store(proxy,reader);
				store.load();
				grid.setStore(store);		
			}
			
	 
			ColumnModel columnModel = getColumnModel();
			
			 grid.setColumnModel(columnModel);
			 grid.setSelectionModel(cbSelectionModel);

			 
    	    return grid;
	    }
	    
	    public void refreshHistoryGrid()
	    {
	    	setColumnNameList();
			Object[][] data = convertRawDataToObjectGrid();

			//The columns names are not determined until after the data Object[][] has been processed
			RecordDef recordDef = buildRecordDef();
			
			
			if (data != null)
			{
				MemoryProxy proxy = new MemoryProxy(data);
				
				ArrayReader reader = new ArrayReader(recordDef);
				Store store = new Store(proxy,reader);
				store.load();
				grid.reconfigure(store,getColumnModel());		
			}
			
	    }  
		private RecordDef buildRecordDef()
		{	
			FieldDef[] sfd = new StringFieldDef[columnNameList.size()];
			
			
			for (int i = 0; i < columnNameList.size(); i++)
			{
				sfd[i] = new StringFieldDef((String)columnNameList.get(i));
			}					
			
			RecordDef recordDef = new RecordDef(sfd);

			return recordDef;
		}
		
		
		private ColumnModel getColumnModel()
		{
			BaseColumnConfig[] columnConfig;
			
			if (columnNameList.size() == 0)			
			{
			    columnConfig = new BaseColumnConfig[columnNameList.size() + 2];
				ColumnConfig ccNoData = new ColumnConfig("Empty","Empty",100);
				columnConfig[1] = ccNoData;			    
			}
			else
				columnConfig = new BaseColumnConfig[columnNameList.size() + 1];
			
			 			
				columnConfig[0] = new CheckboxColumnConfig(cbSelectionModel);
				
				for (int i = 0; i < columnNameList.size(); i++)
				{
					int width = 100;
					if (i == 1)
						width = 150;
					if (i == 4)
						width = 250;
					ColumnConfig cc = new ColumnConfig((String)columnNameList.get(i),(String)columnNameList.get(i),width);
					//cc.setAlign(TextAlign.RIGHT);
					columnConfig[i + 1] = cc;
				}					

				 ColumnModel columnModel = new ColumnModel(columnConfig);

			return columnModel;
		}
		
		private void setColumnNameList()
		{
			if (historyData != null)
			{			
				columnNameList = new ArrayList();
				columnNameList.add("Search Id");
				columnNameList.add("Submit TS");
				columnNameList.add("Start TS");
				columnNameList.add("End TS");
				columnNameList.add("Search Criteria");
				int[] typeIds = client.getAllTypes();
				
				for (int i = 0; i < typeIds.length; i++)
				{
					columnNameList.add(client.getTypeName(typeIds[i]));			
				}
			}
		}
		
		private ArrayList columnNameList;
		
		/**
		 * This converts the incoming data object a HashMap or an ArrayList into a Object[][]
		 */
		private Object[][] convertRawDataToObjectGrid()
		{
			int columns = columnNameList.size() + 1;
			
			Object[][] displayData = null;
			
			if (historyData != null)
			{
				displayData = new Object[historyData.length][columns];
				
				QueryOptions qo = null;
				int recordCount = 0;
				for (int i = 0; i < historyData.length; i++)
				{
					int recordCol = 0;
					qo = historyData[i];
					displayData[recordCount][recordCol++] = qo.queryID;
					displayData[recordCount][recordCol++] = qo.ts + "";
					displayData[recordCount][recordCol++] = qo.startTS + "";
					displayData[recordCount][recordCol++] = qo.endTS + "";
					
                    if (qo.queryType == GUIUtil.QUERY_TYPE_IPS) {
                    	displayData[recordCount][recordCol++] = "IP Search: " + qo.getIPsString();
                    } else if (qo.queryType == GUIUtil.QUERY_TYPE_SEARCH) {
                    	displayData[recordCount][recordCol++] = "General Search: " + qo.getSearchString();
                    } 
					
					for (int j = 0; j < client.getAllTypes().length; j++)
					{
                        if (qo.isSelected(client.getAllTypes()[j])) {
                        	displayData[recordCount][recordCol++] =  "<img src=\"image/checkmark.gif\">";
                        } else
                        	displayData[recordCount][recordCol++] =  " ";
						
					}								
					recordCount++;
				}					
				
			}
			else
			{
				displayData = new Object[1][1];
			}
			
			return displayData;
		}
	    
	    
}
